package ac.aiit.tw;

import java.io.IOException;
import java.util.ArrayList;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;

import twitter4j.DirectMessage;
import twitter4j.StallWarning;
import twitter4j.Status;
import twitter4j.StatusDeletionNotice;
import twitter4j.StatusListener;
import twitter4j.TwitterStream;
import twitter4j.User;
import twitter4j.UserList;
import twitter4j.UserStreamListener;
import ac.aiit.tw.serialCommand.ICommMessageListener;
import ac.aiit.tw.serialCommand.serialCommException;

public class twListener {
//	private static Pattern _filter = Pattern.compile("^.*[^ -~｡-ﾟ]*.*$");

	private static serialCommand_synchronized _comm = null;
	
	private static Configuration _config = null;
	private static ArrayList<String> _queuedMessages = new ArrayList<String>();
	private static synchronized Configuration loadConfig(String path) throws ConfigurationException{
		if(null == _config){
			Configuration cfg = new PropertiesConfiguration(path);
			_config = cfg.subset(twListener.class.getName());
		}
		return _config;
	}

	private static final String Prop_comPort = "comPort";
	public static void showMessage(String msg){
		try {
			String command = "u6l1800e";
			if(_queuedMessages.size() > 0){
				command = "u6w30e";
			}
			if(_comm.write(_config.getString("command", command))){
				_queuedMessages.clear();
				System.out.println(String.format("sent message:%s", msg));
			}else{
				_queuedMessages.add(msg);
				System.out.println(String.format("skip message(in flight):%s", msg));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	private static final void startSample(){
	    StatusListener listener = new StatusListener(){
	        public void onStatus(Status status) {
	        	String msg = status.getText();
//	        	Matcher m = _filter.matcher(msg);
	        	
	        	if(status.isRetweet()){
	        		try {
	        			if(_comm.write(new Integer(2))){
	        				System.out.println(String.format("sent message:%s", msg));
	        			}else{
	        				System.out.println(String.format("skip message(in flight):%s", msg));
	        			}
					} catch (IOException e) {
						e.printStackTrace();
					}
	        	}
	 //           System.out.println(status.getUser().getName() + " : " + status.getText());
	        }
	        public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) {}
	        public void onTrackLimitationNotice(int numberOfLimitedStatuses) {}
	        public void onException(Exception ex) {
	            ex.printStackTrace();
	        }
			@Override
			public void onScrubGeo(long arg0, long arg1) {
				// TODO Auto-generated method stub
				
			}
			@Override
			public void onStallWarning(StallWarning arg0) {
				// TODO Auto-generated method stub
				
			}
	    };
	    TwitterStream twitterStream = twFactory.getStreamInstance(_config);
	    twitterStream.addListener(listener);
	    twitterStream.sample();
	}
	
	private static final void startUser(){
		UserStreamListener listener = new UserStreamListener(){

			@Override
			public void onDeletionNotice(StatusDeletionNotice arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onScrubGeo(long arg0, long arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onStallWarning(StallWarning arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onStatus(Status status) {
	        	String msg = status.getText();
//	        	Matcher m = _filter.matcher(msg);
	        	
//	        	if(status.isRetweet()){

	        	showMessage(msg);
//	        	}
	 //           System.out.println(status.getUser().getName() + " : " + status.getText());
	        }

			@Override
			public void onTrackLimitationNotice(int arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onException(Exception arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onBlock(User arg0, User arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onDeletionNotice(long arg0, long arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onDirectMessage(DirectMessage arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onFavorite(User arg0, User arg1, Status arg2) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onFollow(User arg0, User arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onFriendList(long[] arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUnblock(User arg0, User arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUnfavorite(User arg0, User arg1, Status arg2) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUserListCreation(User arg0, UserList arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUserListDeletion(User arg0, UserList arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUserListMemberAddition(User arg0, User arg1,
					UserList arg2) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUserListMemberDeletion(User arg0, User arg1,
					UserList arg2) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUserListSubscription(User arg0, User arg1,
					UserList arg2) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUserListUnsubscription(User arg0, User arg1,
					UserList arg2) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUserListUpdate(User arg0, UserList arg1) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onUserProfileUpdate(User arg0) {
				// TODO Auto-generated method stub
				
			}
			
		};
	    TwitterStream twitterStream = twFactory.getStreamInstance(_config);
	    twitterStream.addListener(listener);
	    _comm.addMessageListener(new ICommMessageListener(){

			@Override
			public void onMessage(String text) throws serialCommException {
				if(_queuedMessages.size() > 0){
					StringBuilder sb = new StringBuilder();
					for(String msg: _queuedMessages){
						if(sb.length() > 0){
							sb.append(", ");
						}
						sb.append(msg);
					}
					showMessage(sb.toString());
				}
			}
	    	
	    });
	    twitterStream.user();
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			String cfgPath =  "twl.properties";
			if(0 < args.length){
				cfgPath = args[0];
			}
			Configuration config = loadConfig(cfgPath);
			String comPort = config.getString(Prop_comPort);
			if(null == comPort || comPort.length() == 0){
				System.out.println(String.format("%s.%s is not specified"
						,twListener.class.getName(), Prop_comPort));
				return;
			}
			_comm = serialCommand_synchronized.getInstance(comPort);//change here to match your environment.
			//startSample();
			startUser();
		} catch (ConfigurationException e) {
			e.printStackTrace();
		} catch (serialCommException e) {
			e.printStackTrace();
		}

	}

}
